/*
 * SetupSaleItem.java
 *
 * Created on 31-Mar-2011, 10:56:22 PM
 *
 * TODO: EmployeeId
 */

package pos.ui.screen.administrator;

import pos.control.PromotionControl;
import pos.entity.Promotion;
import java.text.ParseException;
import javax.swing.JOptionPane;
import java.sql.Date;
import pos.interfaces.Messages;
import javax.swing.text.MaskFormatter;
import java.util.ArrayList;
import java.util.ListIterator;
import pos.entity.Promotion.PromotionType;
import javax.swing.DefaultComboBoxModel;

/**
 * The setupSaleItem form, which allows an administrator to create a new
 * promotion (sale), with all required information
 * @author Justin Hume
 */
public class SetupSaleItem extends javax.swing.JPanel {

    // -------------------------------------------------------------------------
    //  Constructor
    // -------------------------------------------------------------------------
    public SetupSaleItem() {
        initComponents();

        //Set input masks on required fields
        this.setMaskOnStartDate();
        this.setMaskOnEndDate();
        this.setMaskOnDiscount();

        //Set the enum form the promotion combo box
        setEnumForPromotionType();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        txtName = new javax.swing.JTextField();
        jLabel8 = new javax.swing.JLabel();
        jLabel6 = new javax.swing.JLabel();
        ftxStartDate = new javax.swing.JFormattedTextField();
        cmbPromotionType = new javax.swing.JComboBox();
        ftxEndDate = new javax.swing.JFormattedTextField();
        btnOK = new javax.swing.JButton();
        ftxDiscount = new javax.swing.JFormattedTextField();
        jLabel5 = new javax.swing.JLabel();
        jLabel7 = new javax.swing.JLabel();
        jLabel4 = new javax.swing.JLabel();
        jSeparator1 = new javax.swing.JSeparator();
        jLabel1 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jScrollPane1 = new javax.swing.JScrollPane();
        txaDescription = new javax.swing.JTextArea();
        jScrollPane2 = new javax.swing.JScrollPane();
        txaConditions = new javax.swing.JTextArea();

        txtName.setFont(new java.awt.Font("Tahoma", 0, 12));

        jLabel8.setFont(new java.awt.Font("Tahoma", 0, 12));
        jLabel8.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        jLabel8.setText("Promotion Conditions");

        jLabel6.setFont(new java.awt.Font("Tahoma", 0, 12));
        jLabel6.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        jLabel6.setText("Promotion Name");

        ftxStartDate.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.DateFormatter(new java.text.SimpleDateFormat("dd-MMM-yyyy"))));
        ftxStartDate.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                ftxStartDatePropertyChange(evt);
            }
        });

        cmbPromotionType.setFont(new java.awt.Font("Tahoma", 0, 12));

        ftxEndDate.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.DateFormatter(new java.text.SimpleDateFormat("dd-MMM-yyyy"))));
        ftxEndDate.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                ftxEndDatePropertyChange(evt);
            }
        });

        btnOK.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
        btnOK.setText("OK");
        btnOK.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                btnOKMouseClicked(evt);
            }
        });

        ftxDiscount.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.NumberFormatter(new java.text.DecimalFormat("#0%"))));
        ftxDiscount.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                ftxDiscountPropertyChange(evt);
            }
        });

        jLabel5.setFont(new java.awt.Font("Tahoma", 0, 12));
        jLabel5.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        jLabel5.setText("Promotion Discount (%)");

        jLabel7.setFont(new java.awt.Font("Tahoma", 0, 12));
        jLabel7.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        jLabel7.setText("Promotion Description");

        jLabel4.setFont(new java.awt.Font("Tahoma", 0, 12));
        jLabel4.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        jLabel4.setText("Type of Promotion");

        jLabel1.setFont(new java.awt.Font("Tahoma", 0, 18));
        jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel1.setText("Promotion Setup");

        jLabel3.setFont(new java.awt.Font("Tahoma", 0, 12));
        jLabel3.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        jLabel3.setText("End Date (dd-MMM-yyyy)");

        jLabel2.setFont(new java.awt.Font("Tahoma", 0, 12));
        jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        jLabel2.setText("Start Date (dd-MMM-yyyy)");

        txaDescription.setColumns(20);
        txaDescription.setRows(5);
        jScrollPane1.setViewportView(txaDescription);

        txaConditions.setColumns(20);
        txaConditions.setRows(5);
        jScrollPane2.setViewportView(txaConditions);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                        .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 152, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(ftxEndDate, javax.swing.GroupLayout.DEFAULT_SIZE, 210, Short.MAX_VALUE))
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                        .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 152, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(ftxStartDate, javax.swing.GroupLayout.DEFAULT_SIZE, 210, Short.MAX_VALUE))
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                        .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, 152, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(ftxDiscount, javax.swing.GroupLayout.DEFAULT_SIZE, 210, Short.MAX_VALUE))
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                        .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, 152, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(cmbPromotionType, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                .addContainerGap(241, Short.MAX_VALUE))
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jSeparator1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 552, Short.MAX_VALUE)
                    .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, 552, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, 135, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, 135, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(18, 18, 18)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 399, Short.MAX_VALUE)
                            .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 399, Short.MAX_VALUE)))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, 135, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(txtName, javax.swing.GroupLayout.DEFAULT_SIZE, 399, Short.MAX_VALUE)))
                .addGap(51, 51, 51))
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap(512, Short.MAX_VALUE)
                .addComponent(btnOK, javax.swing.GroupLayout.PREFERRED_SIZE, 91, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(16, 16, 16)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(txtName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel6))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 104, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel7))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel8)
                    .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 104, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(9, 9, 9)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel2)
                    .addComponent(ftxStartDate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(8, 8, 8)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel3)
                    .addComponent(ftxEndDate, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel5)
                    .addComponent(ftxDiscount, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(cmbPromotionType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel4))
                .addGap(30, 30, 30)
                .addComponent(btnOK, javax.swing.GroupLayout.DEFAULT_SIZE, 37, Short.MAX_VALUE)
                .addContainerGap())
        );
    }// </editor-fold>//GEN-END:initComponents

    // -------------------------------------------------------------------------
    //  Events related to validation of input on the form
    // -------------------------------------------------------------------------
    private void ftxStartDatePropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_ftxStartDatePropertyChange

        //If null, then user input value was invalid
        if (evt.getNewValue() == null) {
            this.setMaskOnStartDate();
        }
}//GEN-LAST:event_ftxStartDatePropertyChange
    private void ftxEndDatePropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_ftxEndDatePropertyChange

        //If null, then user input value was invalid
        if (evt.getNewValue() == null) {
            this.setMaskOnEndDate();
        }
}//GEN-LAST:event_ftxEndDatePropertyChange

    private void btnOKMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_btnOKMouseClicked

        if (fieldsAreValid(true)){

            addPromotion();
        }
    }//GEN-LAST:event_btnOKMouseClicked

    private void ftxDiscountPropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_ftxDiscountPropertyChange

        //If null, then user input value was invalid
        if (evt.getNewValue() == null) {
            this.setMaskOnDiscount();
        }
}//GEN-LAST:event_ftxDiscountPropertyChange

    // -------------------------------------------------------------------------
    //  Private methods
    // -------------------------------------------------------------------------
    /**
     * Sets an input mask on the startDate field
     */
    private void setMaskOnStartDate() {

        //Instal mask formatters on the relevant text fields
        try {
            //End date
            MaskFormatter endFormatter = new MaskFormatter("##-UUU-####");
            endFormatter.install(ftxStartDate);
        }
        catch (ParseException pe) {
            //Empty exception. Shouldn't be one.
        }
    }

    /**
     * Sets an input mask on the endDate field
     */
    private void setMaskOnEndDate() {

        //Instal mask formatters on the relevant text fields
        try {
            //End date
            MaskFormatter endFormatter = new MaskFormatter("##-UUU-####");
            endFormatter.install(ftxEndDate);
        }
        catch (ParseException pe) {
            //Empty exception. Shouldn't be one.
        }
    }

    /**
     * Sets a mask on the discount field
     */
    private void setMaskOnDiscount() {

        //Instal mask formatters on the relevant text fields
        try {
            //End date
            MaskFormatter discountFormatter = new MaskFormatter("##%");
            discountFormatter.install(ftxDiscount);
        }
        catch (ParseException pe) {
            
        }
    }

    /**
     * Sets the PromotionType enum as th set of values for the promotion type
     * combo box
     */
    private void setEnumForPromotionType() {

        this.cmbPromotionType.setModel(new DefaultComboBoxModel(PromotionType.values()));
    }

    /**
     * This method ensures that all fields have valid values. A message is
     * given to the user if one or a number of fields has an invalid value. The
     * message indicates which fields are invalid
     */
    private boolean fieldsAreValid(boolean giveMessageToUser) {

        boolean allFieldsAreValid = true;

        //Create a list of messages for each invalid field
        ArrayList<String> invalidFieldMessageList = new ArrayList<String>();

        //Check that all fields are non-empty and otherwise valid
        if (txtName.getText().length() == 0) {

            allFieldsAreValid = false;

            invalidFieldMessageList.add("Enter a promotion name.");
        }

        if (txaDescription.getText().length() == 0) {

            allFieldsAreValid = false;

            invalidFieldMessageList.add("Enter a promotion Description.");
        }

        if (txaConditions.getText().length() == 0) {

            allFieldsAreValid = false;

            invalidFieldMessageList.add("Enter promotion conditions.");
        }

        if (ftxStartDate.getValue() == null) {

            allFieldsAreValid = false;

            invalidFieldMessageList.add("Enter a promotion start date.");
        }

        if (ftxEndDate.getValue() == null) {

            allFieldsAreValid = false;

            invalidFieldMessageList.add("Enter a promotion end date.");
        }

        if (ftxDiscount.getValue() == null) {

            allFieldsAreValid = false;

            invalidFieldMessageList.add("Enter a promotion discount between 1% and 99%.");
        }
        //Check that discount is in allowable range (1% to 99%)
        // NOTE: Ideally, this logic should be contained in the promotion entity class
        else if ((Double)ftxDiscount.getValue() > 0.99 ||
                 (Double)ftxDiscount.getValue() < 0.01) {

            allFieldsAreValid = false;
        }

        //Give the user a message if this is required
        if (giveMessageToUser && !invalidFieldMessageList.isEmpty())
        {
            //Create a string of
            String invalidString = "";

            ListIterator<String> invalidListIter = invalidFieldMessageList.listIterator();

            //Concatenate each message. Each message should be on a new line, hence
            //the new line character
            while (invalidListIter.hasNext()) {

                invalidString = invalidString + invalidListIter.next() + "\n";
            }

            //Display the message
            JOptionPane.showMessageDialog(this, invalidString, Messages.infoDialogTitle, JOptionPane.ERROR_MESSAGE);
        }

        return allFieldsAreValid;
    }

    /**
     * Creates a promotion entity and promotion control object, sets the fields
     * on the promotion entity and adds it to the repository
     */
    private void addPromotion() {

        //Create promotion controller and entity
        PromotionControl promoControl = new PromotionControl();
        Promotion promo = new Promotion();

        //Set fields on promotion entity
        promo.setPromotionName(txtName.getText());
        promo.setPromotionDescription(txaDescription.getText());
        promo.setPromotionConditions(txaConditions.getText());


        //Convert sql.date types from util.date types

        //Start date field
        java.util.Date utilDate = (java.util.Date)ftxStartDate.getValue();
        Date sqlStartDate = new Date(utilDate.getTime());

        promo.setPromotionStartDateTime(sqlStartDate);

        //End date field
        utilDate = (java.util.Date)ftxEndDate.getValue();
        Date sqlEndDate = new Date(utilDate.getTime());

        promo.setPromotionEndDateTime(sqlEndDate);


        //Remaining fields
        promo.setPromotionPriceAdjustment((Double)ftxDiscount.getValue());
        promo.setPromotionCreatedByEmployeeId(0);
        promo.setDateTimeCreated(new Date(System.currentTimeMillis()));
        promo.setDateTimeModified(new Date(System.currentTimeMillis()));
        promo.setPromotionType((PromotionType)cmbPromotionType.getSelectedItem());


        //Get control object to update persistance store
        promoControl.add(promo);
        
        //Clear the form of fields with data
        clearFormFieldValues();

        //Display the message
        JOptionPane.showMessageDialog(this, "A new promotion has been added", "Success!", JOptionPane.INFORMATION_MESSAGE);

    }

    /**
     * This method clears all the values in the fields on the form
     */
    private void clearFormFieldValues() {

        //clear the text or value from each field
        txtName.setText(null);
        txaDescription.setText(null);
        txaConditions.setText(null);
        ftxStartDate.setValue(null);
        ftxEndDate.setValue(null);
        ftxDiscount.setValue(null);
    }

    //Override the toString method
    public String toString(){
        return "Setup Promotion";
    }


    // -------------------------------------------------------------------------
    //  Private fields for form
    // -------------------------------------------------------------------------
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnOK;
    private javax.swing.JComboBox cmbPromotionType;
    private javax.swing.JFormattedTextField ftxDiscount;
    private javax.swing.JFormattedTextField ftxEndDate;
    private javax.swing.JFormattedTextField ftxStartDate;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JTextArea txaConditions;
    private javax.swing.JTextArea txaDescription;
    private javax.swing.JTextField txtName;
    // End of variables declaration//GEN-END:variables

}
